home *** CD-ROM | disk | FTP | other *** search
- /*
- HappyHappy.c
-
- HappyHappy extension. Demonstrates use of PatchWorks trap patching
- system to patch DrawString. Uses new GenericPatch class.
-
- by Mouse Herrell & Patrick Beard.
-
- © 1991 Berkeley Systems Inc.
- */
-
- #include <string.h>
- #include <Notification.h>
- #include <Traps.h>
- #include <stdarg.h>
- #include <stdio.h>
- #include <ctype.h>
- #include <stddef.h>
-
- #include <Exceptions.h>
- #include <Extension.h>
- #include <GenericPatch.h>
-
- static int dprintf(const char* format, ...);
-
- //
- // DrawStringPatch -- HappyHappy of a head-off patch.
- //
-
- class DrawStringPatch : public GenericPatch {
- public:
- DrawStringPatch();
- virtual void Behavior(void);
-
- private:
- long itsCallCount;
- };
-
- struct DrawStringParameters {
- Str255 *theString;
- };
-
- typedef struct DrawStringParameters DrawStringParameters;
-
- typedef pascal long (*DrawStringProcPtr) (Point pt);
-
- DrawStringPatch::DrawStringPatch()
- {
- // initialize instance variables.
- itsCallCount = 0;
-
- // install the appropriate patch.
- GenericPatch::InitGenericPatch(_DrawString, sizeof(DrawStringParameters));
- Install();
- }
-
- void DrawStringPatch::Behavior()
- {
- KeyMap Keys;
- int theLen, index;
- char *buffer;
- int count, Happy;
-
- // announce our presence if control key held down.
- //GetKeys(Keys);
- //if (Keys[1] & 0x8) {
- if (1) { // normally we would check for a message from the Happy Button
- DrawStringParameters* params = (DrawStringParameters*)itsFrame->parameters;
-
- // head off the patch and return.
- //AbortTrap();
-
- theLen = *(params->theString)[0];
- buffer = (char *)(params->theString);
-
- //dprintf("DrawString: params = (%ld), theLen = %x, buffer = %ld",params,theLen,buffer);
- count = 0;
- Happy = 0;
-
- if (theLen > 3)
-
- for (index=1; index <= theLen; index++)
- {
- if (isalpha(buffer[index]))
- {
- if (count == 0)
- if (Happy)
- buffer[index] = 'J';
- else
- buffer[index] = 'H';
- else if (count == 1)
- if (Happy)
- buffer[index] = 'o';
- else
- buffer[index] = 'a';
- else if (count == 2)
- if (Happy)
- buffer[index] = 'o';
- else
- buffer[index] = 'p';
- else
- if (Happy)
- buffer[index] = 'o';
- else
- buffer[index] = 'p';
- count++;
-
- if ((ispunct(buffer[index+1])) || (isspace(buffer[index+1])))
- buffer[index] = 'y';
-
-
- }
- else if (ispunct(buffer[index]))
- {
- count = 0;
- if (Happy)
- Happy = 0;
- else
- Happy = 1;
- }
- else if (isspace(buffer[index]))
- {
- count = 0;
- if (Happy)
- Happy = 0;
- else
- Happy = 1;
- }
- }
- buffer[theLen] = 'y';
-
- }
- }
-
- //
- // Install routine. This is where you allocate your patch objects.
- // Throw an exception if something fails.
- //
-
- void Install()
- {
- try {
- // if extension succeeds, show happy icon.
- new DrawStringPatch;
- ShowIconFamily(128);
- } catch {
- // extension failed, show sad icon.
- ShowIconFamily(129);
- throw(theException);
- }
- }
-
- //
- // Remove routine. This is called when system is shutdown.
- // Perhaps this should be removed. Rob thinks it shouldn't even be
- // part of the design.
- //
-
- void Remove()
- {
- Patch::RemoveAll();
- }
-
- //
- // debugging printf.
- //
-
- static int dprintf(const char* format, ...)
- {
- va_list args;
- static char str[256];
- int count;
-
- va_start(args, format);
- count = vsprintf(str, format, args);
- va_end(args);
- DebugStr(c2pstr(str));
-
- return count;
- }
-